package remoteService;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

import concole.CommandHelper;
import concole.Course;
import concole.IOHelper;
import concole.Student;
import concole.Teacher;
import concole.User;

public class ServerHelper {
	int port = 8000;
	ServerSocket socket = null;

	public ServerHelper() {
		try {
			socket = new ServerSocket(port);
		} catch (IOException e) {
			// TODO: handle exception
			System.out.println("error in serversocketCreate" + e);
		}
	}

	public void startServer() {
		Socket s = null;
		PrintWriter pWriter = null;
		BufferedReader bReader = null;
		// constantly server the user
		while (true) {
			try {
				System.out.println("1");
				s = socket.accept();
				System.out.println("2");
				bReader = new BufferedReader(new InputStreamReader(
						s.getInputStream()));
				pWriter = new PrintWriter(s.getOutputStream());
				String replyString = "";
				String readString = bReader.readLine();
				System.out.println("receiving from client" + readString);
				int cmdInt = CommandHelper.getOperand(readString);
				System.out.println("commandInt:" + cmdInt);
				String opcodeString = CommandHelper.getOpcode(readString);
				String[] opcodeStrings = opcodeString.split("!");
				switch (cmdInt) {
				case 10:
					replyString = IOHelper.findOneRecord(0,
							"loginAccounts.txt", opcodeString);
					System.out.println("create replyString" + replyString);
					break;
				case 11:
					replyString = IOHelper.findOneRecord(0,
							"teacherAccounts.txt", opcodeString);
					break;
				case 12:
					replyString = IOHelper.findOneRecord(0,
							"studentAccounts.txt", opcodeString);

					break;
				case 21:
					replyString = "Successfully";
					IOHelper.writeBackToFile("LoginAccounts.txt", "admin" + " "
							+ opcodeString);
					break;
				case 22:
					replyString = IOHelper.getAllFile(opcodeString);
					System.out.println(replyString);
					replyString = replyString.replace("\n", "!");
					break;
				case 23:
					readString = null;
					IOHelper.deleteOneLine(opcodeStrings[0].trim(),
							Integer.parseInt(opcodeStrings[1].trim()));
					break;
				case 30:

					replyString = IOHelper.findOneRecord(0, "courseList.txt",
							opcodeString);
					System.out.println("end30" + replyString);
					if (replyString == null) {
						replyString = "Fail";
					}
					break;
				case 31:
					Course oldCourse = new Course(opcodeStrings[0]);
					Course newCourse = new Course(opcodeStrings[1]);
					boolean ifCnumChange = opcodeStrings[2].equals("T");
					boolean ifTChange = opcodeStrings[3].equals("F");
					doTask31(oldCourse, newCourse, ifCnumChange, ifTChange);
					break;
				case 32:
					replyString = doTask32(opcodeString);
					break;
				case 33:
					doTask33(new Course(opcodeString));
					break;

				case 34:
					replyString = doTask34(opcodeString);
					break;
				case 35:
					Course oldCourse2 = new Course(opcodeStrings[0]);
					Course newCourse2 = new Course(opcodeStrings[1]);
					doTask35(oldCourse2, newCourse2);
					break;
				case 36:
					System.out.println("Start case36:" + opcodeString);
					replyString = doTask36(opcodeString);
					break;
				case 37:
					replyString = doTask37(opcodeString);
					break;
				case 38:
					replyString = doTask38(opcodeString);
					break;
				case 39:
					doTask39(opcodeString);
					break;
				case 310:
					replyString = IOHelper.findOneRecord(0, "teachersList.txt",
							opcodeString);
					if (replyString == null) {
						replyString = "Fail";
					} else if (replyString.length() == 0) {
						replyString = "Fail";
					}
					break;
				case 41:// processNetGetCourseInfo
					replyString = IOHelper.findOneRecord(0, "courseList.txt",
							opcodeString);
					if (replyString == null) {
						replyString = "Fail";
					}
					break;
				case 42:// processNetHasRight
					replyString = IOHelper.findOneRecord(0, 1,
							"courseSelected.txt", opcodeStrings[0],
							opcodeStrings[1]);
					if (replyString == null || replyString.length() == 0) {
						replyString = "Fail";
					}
					break;
				case 43:// processNetGetScore
					System.out.println(opcodeStrings[0] + " "
							+ opcodeStrings[1]);
					replyString = IOHelper.findOneRecord(1, 0, "Scores.txt",
							opcodeStrings[0], opcodeStrings[1]);
					if (replyString == null || replyString.length() == 0) {
						replyString = "Fail";
					}
					break;
				case 44:// processNetSelectC
					String toStoreString = opcodeStrings[0] + " "
							+ opcodeStrings[1];
					IOHelper.addOneLine("courseSelected.txt", toStoreString);
					replyString = "Success";
					break;
				case 45:// proceessNetQuit
					IOHelper.deleteOneLine("courseSelected.txt", 0,
							opcodeStrings[0], 1, opcodeStrings[1]);
					replyString = "Success";
					break;
				case 46:// processNetShowAllCourse
					replyString = doTask46(opcodeString);
					break;
				case 47:
					Student student = new Student(opcodeString);
					replyString = student.getName();
					System.out.println(replyString);
					break;
				default:
					break;
				}

				pWriter.write(replyString);
				pWriter.flush();
				pWriter.close();
				System.out.println("The reply is " + replyString);
			} catch (Exception e) {
				// TODO: handle exception
				System.err.println(e);
			}
		}
	}

	private String doTask46(String studentNumber) {
		// TODO Auto-generated method stub
		StringBuffer toShow = new StringBuffer();
		String allCourseString = IOHelper.findAllMatchInfo(1,
				"courseSelected.txt", studentNumber);
		if (allCourseString == null || allCourseString.length() == 0) {
			return "Fail";
		}
		if (allCourseString.contains("\n")) {
			String[] allCourse = allCourseString.split("\n");

			for (int i = 0; i < allCourse.length; i++) {
				allCourse[i] = allCourse[i].substring(0,
						allCourse[i].indexOf(" "));
				allCourse[i] = allCourse[i].trim();
				toShow.append(IOHelper.findOneRecord(0, "courseList.txt",
						allCourse[i]));
				toShow.append("\n");
			}
			String toShowString = toShow.toString().trim();
			System.out.println(toShowString);
		} else {
			allCourseString = allCourseString.substring(0,
					allCourseString.indexOf(" "));
			allCourseString = allCourseString.trim();
			toShow.append(IOHelper.findOneRecord(0, "courseList.txt",
					allCourseString));
		}
		System.out.println(toShow.toString().trim().replace("\n", "!"));
		return toShow.toString().trim().replace("\n", "!");
	}

	private void doTask39(String opcodeString) {
		// TODO Auto-generated method stub
		String[] tostoreStrings = opcodeString.split("#");
		for (int i = 0; i < tostoreStrings.length; i++) {
			IOHelper.addOneLine("Scores.txt", tostoreStrings[i]);
		}
	}

	private String doTask38(String courseNum) {
		// TODO Auto-generated method stub
		String resultString = IOHelper.findAllMatchInfo(0,
				"courseSelected.txt", courseNum);
		if (resultString == null) {
			return "Fail";
		} else if (resultString.length() == 0) {
			return "Fail";
		}
		resultString = resultString.replace("\n", "!");

		System.out.println("getResultIn doTask38" + resultString);

		return resultString;
	}

	private String doTask37(String courseNum) {
		// TODO Auto-generated method stub
		String string = IOHelper.findAllMatchInfo(1, "Scores.txt", courseNum);

		return string;
	}

	private String doTask36(String teacherNum) {
		// TODO Auto-generated method stub
		/*
		 * System.out.println("getIOhelper"+courseNum); String string =
		 * IOHelper.findAllMatchInfo(0, "courseSelected.txt", courseNum);
		 */
		String string = IOHelper.findAllRegionMatches(3, "CourseList.txt",
				teacherNum);
		string = string.replaceAll("\n", "!");
		System.out.println("getIOhelper\n" + string);

		return string;
	}

	private void doTask35(Course oldCourse2, Course newCourse2) {
		// TODO Auto-generated method stub
		IOHelper.replaceOneRecord("courseList.txt", oldCourse2.toStoreString(),
				newCourse2.toStoreString());
	}

	private String doTask34(String opcodeString) {
		// TODO Auto-generated method stub
		String reply = IOHelper
				.findOneRecord(0, "courseList.txt", opcodeString);
		if (reply == null) {
			System.out.println("In do task34 findNULL");
			return "Fail";
		} else if (reply.length() == 0) {
			System.out.println("In do task34 find length0");
			return "Fail";
		}
		return reply;
	}

	private void doTask33(Course course) {
		// TODO Auto-generated method stub
		IOHelper.addOneLine("courseList.txt", course.toStoreString());
		/*
		 * refresh the file of teacher and add the courseNum to the specific
		 * record
		 */
		for (int i = 0; i < course.teachers.size(); i++) {
			IOHelper.addToLineEnd("teachersList.txt", course.teachers.get(i)
					.getNum(), 0, course.getCourseNumber());
		}
	}

	private String doTask32(String numString) {
		// TODO Auto-generated method stub
		String resultString = "";
		String[] strings = null;
		StringBuffer bf = new StringBuffer();
		if (numString.contains("&")) {
			strings = numString.split("&");
			for (int i = 0; i < strings.length; i++) {
				bf.append((new Teacher(strings[i]).setNameFromFile()) + "&");
			}
		} else {
			bf.append((new Teacher(numString).setNameFromFile()));
		}
		resultString = bf.toString();
		if (resultString.trim().endsWith("&")) {
			resultString = resultString.substring(0,
					resultString.lastIndexOf("&"));
		}
		System.out.println(resultString);
		return resultString;
	}

	private void doTask31(Course oldCourse, Course newCourse,
			boolean ifCnumChange, boolean ifTChange) {
		// TODO Auto-generated method stub
		if (ifCnumChange) {
			for (int i = 0; i < oldCourse.teachers.size(); i++) {
				IOHelper.replaceOneTermOfLine("teachersList.txt", oldCourse
						.getCourseNumber(), newCourse.getCourseNumber(),
						oldCourse.teachers.get(i).getNum(), 2, 0);
			}
			String oldNum = oldCourse.getCourseNumber();
			String newNum = newCourse.getCourseNumber();
			IOHelper.replaceOneTermOfLine("courseSelected.txt", oldNum, newNum, oldNum, 0, 0);
			IOHelper.replaceOneTermOfLine("Scores.txt", oldNum, newNum,oldNum, 1, 1);
		}
		if (ifTChange) {
			for (int i = 0; i < oldCourse.teachers.size(); i++) {
				IOHelper.removeOneTermFromLine("teachersList.txt", newCourse
						.getCourseNumber(), oldCourse.teachers.get(i).getNum(),
						2, 0);
			}
			for (int i = 0; i < newCourse.teachers.size(); i++) {
				IOHelper.addToLineEnd("teachersList.txt", newCourse.teachers
						.get(i).getNum(), 0, newCourse.getCourseNumber());
			}
		}
	}

	public void stopServer() {
		try {
			socket.close();
		} catch (IOException e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}

}
